package org.zachary.commonservice.strategy.factory;

import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.zachary.commonservice.entity.CreditScoreStrategy;
import org.zachary.commonservice.entity.ServiceType;
import org.zachary.commonservice.mapper.StrategyMapper;

import org.zachary.commonservice.strategy.CreditStrategy;

import java.util.List;
import java.util.Map;
import java.util.NavigableMap;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@Component
public class StrategyFactory {
    @Autowired
    private StrategyRegistry registry;
    @Autowired
    private StrategyMapper strategyRepo;

    private final Map<ServiceType, NavigableMap<Integer, CreditStrategy>> cache = new ConcurrentHashMap<>();


    @PostConstruct
    public void init() {
        for (ServiceType type : ServiceType.values()) {
            reloadStrategies(type);
        }
    }

    public void reloadStrategies(ServiceType type) {
        List<CreditScoreStrategy> configs = strategyRepo.selectByServiceName(type.toString());

        NavigableMap<Integer, CreditStrategy> rangeMap = new TreeMap<>();
        AtomicInteger cnt= new AtomicInteger();
        configs.forEach(config -> {
            CreditStrategy strategy = registry.getStrategy(type);

            System.out.println("策略："+strategy);

            log.info("策略"+(cnt.getAndIncrement())+" 正在加载 "+strategy);

            rangeMap.put(config.getDown(), strategy);
        });
        System.out.println(rangeMap);
        cache.put(type, rangeMap);
        log.info("策略初始化完成："+cache);
    }

    public CreditStrategy getStrategy(ServiceType type, int userScore) {
        NavigableMap<Integer, CreditStrategy> rangeMap = cache.get(type);
        Map.Entry<Integer, CreditStrategy> entry = rangeMap.floorEntry(userScore);
        log.info("本次加载的策略为：{}",entry);
        return entry != null ? entry.getValue() : null;
    }
}